Namespace Core
  Public Class Column
#Region "Private Members"
    Private _parent As Object
    Private _IsSystemColumn As Boolean
    Private _UpdateOnUpdate As Boolean
    Private _DefaultValue As String

    Private mName As String
    Private mType As String
    Private mLength As Integer
    Private mPrecision As Integer
    Private mScale As Integer
    Private mOldStatus As ColumnStatuses
    Private mNewStatus As ColumnStatuses
#End Region

#Region "Constructors"
    Sub New(ByVal parent As Object, ByVal row As SqlDataReader)
      If row Is Nothing Then Throw New ArgumentNullException("row")
      _parent = parent
      mName = row("colName")
      mType = row("colType")
      '_IsSystemColumn = False
      mLength = row("colLength")
      mPrecision = row("colPrecision")
      mScale = row("colScale")
    End Sub

    Sub New(ByVal parent As Object, ByVal name As String, ByVal type As String, ByVal length As Integer, ByVal precision As Integer, ByVal scale As Integer, ByVal defaultValue As String, ByVal updateOnUpdate As Boolean)
      _parent = parent
      mName = name
      mType = type
      _IsSystemColumn = True
      _UpdateOnUpdate = updateOnUpdate
      mLength = length
      mPrecision = precision
      mScale = scale
      _DefaultValue = defaultValue
    End Sub
#End Region

#Region "Properties"
    ReadOnly Property Name() As String
      Get
        Return mName
      End Get
    End Property

    ReadOnly Property Type() As String
      Get
        Return mType
      End Get
    End Property

    ReadOnly Property Length() As Integer
      Get
        Return mLength
      End Get
    End Property

    ReadOnly Property Scale() As Integer
      Get
        Return mScale
      End Get
    End Property

    ReadOnly Property Precision() As Integer
      Get
        Return mPrecision
      End Get
    End Property

    Protected Friend Property IsSystemColumn() As Boolean
      Get
        Return _IsSystemColumn
      End Get
      Set(ByVal value As Boolean)
        _IsSystemColumn = value
      End Set
    End Property

    ReadOnly Property UpdateOnUpdate() As Boolean
      Get
        Return _UpdateOnUpdate
      End Get
    End Property

    ReadOnly Property CanBeNull() As Boolean
      Get
        Return Not _IsSystemColumn
      End Get
    End Property

    ReadOnly Property DefaultValue() As String
      Get
        Return _DefaultValue
      End Get
    End Property

    Property OldStatus() As ColumnStatuses
      Get
        Return mOldStatus
      End Get
      Set(ByVal value As ColumnStatuses)
        mOldStatus = value
      End Set
    End Property

    Property NewStatus() As ColumnStatuses
      Get
        Return mNewStatus
      End Get
      Set(ByVal value As ColumnStatuses)
        Select Case value
          Case ColumnStatuses.Installed
            SetInstallAction(ColumnActions.Install)
          Case ColumnStatuses.None
            SetInstallAction(ColumnActions.Remove)
        End Select
      End Set
    End Property

    Property NewStatus2() As Integer
      Get
        Return NewStatus
      End Get
      Set(ByVal value As Integer)
        NewStatus = value
      End Set
    End Property
#End Region

#Region "Methods"
    Sub SetInstallAction(ByVal action As ColumnActions)
      Select Case action
        Case ColumnActions.None
          mNewStatus = mOldStatus
        Case ColumnActions.Install
          If TypeMask(mType) IsNot Nothing Then
            mNewStatus = ColumnStatuses.Installed
          Else
            mNewStatus = ColumnStatuses.None
            MsgBox(String.Format("The column [{0}].[{1}].[{2}] has been skipped due to the following error:{3}- This data type does not support logging", _parent.Schema, _parent.Name, mName, vbCrLf), MsgBoxStyle.Exclamation Or MsgBoxStyle.OkOnly)
          End If
        Case ColumnActions.Remove
          mNewStatus = ColumnStatuses.None
#If DEBUG Then
        Case Else
          Stop
#End If
      End Select
    End Sub

    Sub GetScript(ByVal script As List(Of String))
      Dim useSchema As String
      Dim useName As String
      Dim pfx(2) As String
      Dim pfxMax As Integer
      Dim i As Integer

      If _IsSystemColumn = True Then
        useSchema = _parent.Schema
        useName = _parent.Name
        pfx(0) = Nothing
        pfxMax = 0
      Else
        useSchema = _parent.HistorySchema
        useName = _parent.HistoryName
        pfx(0) = PFX_OLD
        pfx(1) = PFX_NEW
        pfxMax = 1
      End If

      If mOldStatus <> mNewStatus Then
        Select Case mNewStatus
          Case ColumnStatuses.Installed
            For i = 0 To pfxMax
              AddScriptItem(script, String.Format("ALTER TABLE [{0}].[{1}] ADD {2};", useSchema, useName, ToString().Replace("[", String.Format("[{0}", pfx(i)))))
            Next
          Case ColumnStatuses.None
            script.Add(Nothing)
            For i = 0 To pfxMax
              AddScriptItem(script, String.Format("IF EXISTS (SELECT * FROM sysObjects WHERE xtype='D' AND id=OBJECT_ID('[DF_{1}_{2}{3}]')){4}" _
                                               & "ALTER TABLE [{0}].[{1}] DROP CONSTRAINT [DF_{1}_{2}{3}];", useSchema, useName, pfx(i), mName, vbCrLf))
            Next
            script.Add(Nothing)
            For i = 0 To pfxMax
              AddScriptItem(script, String.Format("IF EXISTS (SELECT * FROM sysColumns WHERE name='{2}{3}' AND id=OBJECT_ID('[{0}].[{1}]')){4}" _
                                                & "ALTER TABLE [{0}].[{1}] DROP COLUMN [{2}{3}];", useSchema, useName, pfx(i), mName, vbCrLf))
            Next
#If DEBUG Then
          Case Else
            Stop
#End If
        End Select
      End If
    End Sub

    Overrides Function ToString() As String
      Return String.Format("[{0}] {1} {2} {3}", _
                           mName, _
                           String.Format(TypeMask(mType), mType, mLength, IIf(mLength = -1, "MAX", Precision), mPrecision, mScale), _
                           IIf(_IsSystemColumn = True, IIf((_DefaultValue & "").Length > 0, "NOT NULL", "NULL"), "NULL"), _
                           IIf((_DefaultValue & "").Length > 0, String.Format("CONSTRAINT [DF_{0}_{1}] DEFAULT {2}", _parent.Name, mName, _DefaultValue), Nothing))
      'IIf(_IsSystemColumn = True, "NOT NULL", "NULL"), _
    End Function

    Function ToString2() As String
      Return String.Format("[{0}] {1} {2} {3}", _
                           mName, _
                           String.Format(TypeMask(mType), mType, mLength, IIf(mLength = -1, "MAX", Precision), mPrecision, mScale), _
                           IIf(_IsSystemColumn = True, IIf((_DefaultValue & "").Length > 0, "NOT NULL", "NULL"), "NULL"), _
                           IIf((_DefaultValue & "").Length > 0, String.Format("CONSTRAINT [DF_{0}_{1}_{2}] DEFAULT {3}", PFX_SCHEMA, _parent.Name, mName, _DefaultValue), Nothing))
      'IIf(_IsSystemColumn = True, "NOT NULL", "NULL"), _
    End Function
#End Region
  End Class
End Namespace